/*
 * HttpsqsMessageHandler.cpp
 *
 *  Created on: Nov 13, 2011
 *      Author: hao
 */

#include "HttpsqsMessageHandler.hpp"
#include <iostream>
#include <xercesc/parsers/SAXParser.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <string.h>
#include <sstream>

#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMWriter.hpp>
//#include <xercesc/dom/DOMLSOutput.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>
#include <xercesc/framework/StdOutFormatTarget.hpp>
using namespace std;

HttpsqsMessageHandler::HttpsqsMessageHandler(){
	// TODO Auto-generated constructor stub

}

HttpsqsMessageHandler::~HttpsqsMessageHandler(){
	// TODO Auto-generated destructor stub
}

HttpsqsMessage *HttpsqsMessageHandler::getHttpsqsMessage() const
{
    return httpsqsMessage;
}

void HttpsqsMessageHandler::setHttpsqsMessage(HttpsqsMessage *httpsqsMessage)
{
    this->httpsqsMessage = httpsqsMessage;
}



void HttpsqsMessageHandler::startDocument(){
	httpsqsMessage = new HttpsqsMessage();


}

void HttpsqsMessageHandler::startElement(const XMLCh* const name,
		AttributeList& attributes) {
	preTag = XMLString::transcode(name);
	//cout << "I saw element: " << preTag << endl;
	//memcpy(preTag, message, strlen(message));
	//preTag = XMLString::transcode(name);;
	//XMLString::release(&message);
}

void HttpsqsMessageHandler::endElement(const XMLCh* const name){
	preTag = NULL;
}
/*void HttpsqsMessageHandler::characters(  const   XMLCh* const   ch
								    , const XMLSize_t       length){
	if (preTag != NULL) {
			if((!strcmp(preTag, "messageId"))){
				//cout  << XMLString::transcode(ch) << endl;
				httpsqsMessage->setMessageId(XMLString::transcode(ch));
			}else if((!strcmp(preTag, "message_body"))){
				//cout << "hh " << XMLString::transcode(ch) << endl;
				httpsqsMessage->setMessageBody(XMLString::transcode(ch));
			}
	}

}*/
void HttpsqsMessageHandler::characters(const XMLCh* const ch, const unsigned int length) {

	if (preTag != NULL) {
		if((!strcmp(preTag, "messageId"))){
			//cout  << XMLString::transcode(ch) << endl;
			httpsqsMessage->setMessageId(XMLString::transcode(ch));
		}else if((!strcmp(preTag, "message_body"))){
			//cout << "hh " << XMLString::transcode(ch) << endl;
			httpsqsMessage->setMessageBody(XMLString::transcode(ch));
		}
	}
}

void HttpsqsMessageHandler::fatalError(const SAXParseException& exception) {
	char* message = XMLString::transcode(exception.getMessage());
	cout << "Fatal Error: " << message << " at line: "
			<< exception.getLineNumber() << endl;
	XMLString::release(&message);
}

void HttpsqsMessageHandler::getHttpsqsMessage(const string xmlstr) {

	//InputStream readStream = new ByteArrayInputStream(xmlstr.c_str());
	const char*  gMemBufId = "prodInfo";

	try {
		XMLPlatformUtils::Initialize();
	} catch (const XMLException& toCatch) {
		char* message = XMLString::transcode(toCatch.getMessage());
		cout << "Error during initialization! :\n" << message << "\n";
		XMLString::release(&message);
		//return;
	}

	//char* xmlFile = "message.xml";

	SAXParser* parser = new SAXParser();
	//parser->setDoValidation(true);
	parser->setDoNamespaces(true); // optional

	DocumentHandler* docHandler = new HttpsqsMessageHandler();
	ErrorHandler* errHandler = (ErrorHandler*) docHandler;
	parser->setDocumentHandler(docHandler);
	parser->setErrorHandler(errHandler);

	MemBufInputSource* memBufIS = new MemBufInputSource
			    (
			        (const XMLByte*)xmlstr.c_str()
			        , strlen(xmlstr.c_str())
			        , gMemBufId
			        , false
			    );

	try {
		parser->parse(*memBufIS);
		//return docHandler->getHttpsqsMessage();

	} catch (const XMLException& toCatch) {
		char* message = XMLString::transcode(toCatch.getMessage());
		cout << "Exception message is: \n" << message << "\n";
		XMLString::release(&message);
		//return -1;
	} catch (const SAXParseException& toCatch) {
		char* message = XMLString::transcode(toCatch.getMessage());
		cout << "Exception message is: \n" << message << "\n";
		XMLString::release(&message);
		//return -1;
	} catch (...) {
		cout << "Unexpected Exception \n";
		//return -1;
	}
	//cout << ((HttpsqsMessageHandler*)docHandler)->httpsqsMessage->getMessageBody() << endl;

	this->setHttpsqsMessage(((HttpsqsMessageHandler*)docHandler)->getHttpsqsMessage());
	delete parser;
	delete docHandler;

}

string HttpsqsMessageHandler::getXMLFromHttpsqsMessage(HttpsqsMessage *httpsqsMessage)
{
	string xml_return="";
	try {
			XMLPlatformUtils::Initialize();
	} catch (const XMLException& toCatch) {
			// Do your failure processing here
			return xml_return;
	}


	DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(X("Core"));

	if (impl != NULL) {
		try {
			DOMDocument* doc = impl->createDocument(0, // root element namespace URI.
					X("httpsqsmessage"), // root element name
					0); // document type object (DTD).

			DOMElement* rootElem = doc->getDocumentElement();
			//message header
			DOMElement* headerElem = doc->createElement(X("httpmessage-header"));
			rootElem->appendChild(headerElem);

			DOMElement* msgIdElem = doc->createElement(X("messageId"));
			headerElem->appendChild(msgIdElem);

			DOMText* messageid = doc->createTextNode(X(httpsqsMessage->getMessageId().c_str()));
			msgIdElem->appendChild(messageid);

			DOMElement* destElem = doc->createElement(X("destination"));
			headerElem->appendChild(destElem);

			DOMText* dest = doc->createTextNode(X(httpsqsMessage->getDestination().c_str()));
			destElem->appendChild(dest);

			//message body
			DOMElement* msgbodyElem = doc->createElement(X("httpmessage_body"));
			rootElem->appendChild(msgbodyElem);

			DOMElement* msgElem = doc->createElement(X("message_body"));
			msgbodyElem->appendChild(msgElem);

			DOMText* msgbody = doc->createTextNode(X(httpsqsMessage->getMessageBody().c_str()));
			msgElem->appendChild(msgbody);

			//
			// Now count the number of elements in the above DOM tree.
			//
			// construct the DOMWriter
			DOMWriter* myWriter = ((DOMImplementationLS*)impl)->createDOMWriter();

			// serialize a DOMNode to a UTF-16 string
			XMLCh* theXMLString_Unicode = myWriter->writeToString(*doc);
			xml_return = XMLString::transcode(theXMLString_Unicode);

			doc->release();
		} catch (const OutOfMemoryException&) {
			XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;

		}
		catch (const DOMException& e)
		{
			XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
		}
		catch (...)
		{
			XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
		}
	} // (inpl != NULL)
	else
	{
		XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
	}
	XMLPlatformUtils::Terminate();
	delete impl;
	return xml_return;
}

/*
int main(int argc, char* args[]) {


	//string xmlFile = "message.xml";
	string xmlFile = "<httpsqsmessage><httpsqsmessage-header><messageId>1212</messageId><destination>test_app_send</destination></httpsqsmessage-header><httpsqsmessage-body><message_body>DTN_Send</message_body></httpsqsmessage-body></httpsqsmessage>";
	HttpsqsMessageHandler* handler = new HttpsqsMessageHandler();
	handler->getHttpsqsMessage(xmlFile);
	cout << handler->getHttpsqsMessage()->getMessageBody() << endl;
	cout << handler->getHttpsqsMessage()->getMessageId() << endl;

	cout << handler->getXMLFromHttpsqsMessage(handler->getHttpsqsMessage())<<endl;
	//get httpsqsmessage to xml



	// Other terminations and cleanup.
	return 0;
}*/
/*
 * Element root = new Element("httpsqsmessage");
		Document doc = new Document(root);
		// construct Header
		Element elementHeader = new Element("");
		elementHeader.addContent(new Element("").setText(hsm
				.getMessageId()));
		elementHeader.addContent(new Element("destination").setText(hsm
				.getMessageId()));
		root.addContent(elementHeader);

		// construct body
		Element elementBody = new Element("");
		elementBody.addContent(new Element("").setText(hsm
				.getMessage_body()));
		root.addContent(elementBody);
		XMLOutputter outputter = new XMLOutputter();
 * */


